extern PyTypeObject PvFrame_Type;
extern PyTypeObject PvWindow_Type;
extern PyObject		*WINDOW_SET;

#define FR_LEAF	0
#define	FR_COL	1
#define	FR_ROW	2

#define FSP_HOR	0	/* frame splited type: horizontal */
#define	FSP_VER	1	/* frame splited type: vertical */

#define FR_LAYOUT(o)	(((PvFrame *)(o))->layout)
#define FR_CHILD(o)		(((PvFrame *)(o))->child)
#define FR_WIN(o)		(((PvFrame *)(o))->win)
#define FR_PARENT(o)	(((PvFrame *)(o))->parent)
#define FR_NEXT(o)		(((PvFrame *)(o))->next)
#define FR_PREV(o)		(((PvFrame *)(o))->prev)
#define FR_HEIGHT(o)	(((PvFrame *)(o))->height)
#define FR_WIDTH(o)		(((PvFrame *)(o))->width)
#define FR_TOP(o)		(((PvFrame *)(o))->top)
#define FR_LEFT(o)		(((PvFrame *)(o))->left)

#define WIN_BUF(o)		(((PvWindow *)(o))->buffer)
#define WIN_FRAME(o)	(((PvWindow *)(o))->frame)
#define WIN_ROW(o)		(((PvWindow *)(o))->row)
#define WIN_COL(o)		(((PvWindow *)(o))->col)
#define WIN_WANTCOL(o)	(((PvWindow *)(o))->wantcol)
#define WIN_TOPLINE(o)	(((PvWindow *)(o))->topline)
#define WIN_LEFTCOL(o)	(((PvWindow *)(o))->leftcol)
#define WIN_TOP(o)		(((PvWindow *)(o))->top)
#define WIN_LEFT(o)		(((PvWindow *)(o))->left)
#define WIN_WIDTH(o)	(((PvWindow *)(o))->width)
#define WIN_HEIGHT(o)	(((PvWindow *)(o))->height)
#define WIN_RIGHT(o)	(WIN_LEFT(o) + WIN_WIDTH(o) - 1)
#define WIN_BOTTOM(o)	(WIN_TOP(o) + WIN_HEIGHT(o) - 1)
#define WIN_ST_H(o)		(((PvWindow *)(o))->status_height)
#define WIN_V_WIDTH(o)	(((PvWindow *)(o))->vsep_width)
#define WIN_LINES(o)	(((PvWindow *)(o))->lines)
#define WIN_TABSTOP(o)	(((PvWindow *)(o))->tabstop)
#define WIN_WCOL(o)		(((PvWindow *)(o))->wcol)
#define WIN_MODE(o)		(((PvWindow *)(o))->mode)

/* the following 2 macro is for map screen pos to win pos */
/* _R mean relative */
#define ROW_SCR2WIN(o, n)	(n - WIN_TOP((o)))
#define COL_SCR2WIN(o, n)	(n - WIN_LEFT((o)))
/* the following 2 macro is for map win pos to screen pos */
/* _A means absolute */
#define ROW_WIN2SCR(o, n)	(n + WIN_TOP((o)))
#define COL_WIN2SCR(o, n)	(n + WIN_LEFT((o)))

#define ROW_BUF2WIN(o, n)	(n - WIN_TOPLINE((o)))
#define COL_BUF2WIN(o, n)	(n - WIN_LEFTCOL((o)))
#define ROW_WIN2BUF(o, n)	(n + WIN_TOPLINE((o)))
#define COL_WIN2BUF(o, n)	(n + WIN_LEFTCOL((o)))

#define ROW_BUF2SCR(o, n)	(ROW_WIN2SCR((o), ROW_BUF2WIN((o), (n))))
#define COL_BUF2SCR(o, n)	(COL_WIN2SCR((o), COL_BUF2WIN((o), (n))))
#define ROW_SCR2BUF(o, n)	(ROW_WIN2BUF((o), ROW_SCR2WIN((o), (n))))
#define COL_SCR2BUF(o, n)	(COL_WIN2BUF((o), COL_SCR2WIN((o), (n))))

/* the offset of the line start character in the window lines */
#define LINE_OFFSET(o, r) (WIN_LINES((o)) + (r) * WIN_WIDTH((o)))
#define BLANK_LINE(o, r, w) Py_UNICODE_FILL(LINE_OFFSET((o), (r)), ' ', (w))

/* tell if a absolute pos (x, y) in the window area range */
#define PvWindow_InWindow(o, x, y) \
	((x) >= WIN_LEFTCOL((o)) && \
	 (y) >= WIN_TOPLINE((o)) && \
	 (x) < COL_WIN2BUF((o),WIN_WIDTH((o))) && \
	 (y) < ROW_WIN2BUF((o),WIN_HEIGHT((o))))
#define PvWindow_CursorInWindow(o) \
	PvWindow_InWindow((o), WIN_WCOL((o)), WIN_ROW((o)))

#define PvWindow_Insert(o, s) \
	PvBuffer_Insert(WIN_BUF((o)), WIN_ROW((o)), WIN_COL((o)), (s))
#define PvWindow_CurChar(o) \
	PyUnicode_AS_UNICODE(PvBuffer_GetLine(WIN_BUF((o)), WIN_ROW((o))))[WIN_COL((o))];

#define PvWindow_CheckExact(op) (Py_TYPE(op) == &PvWindow_Type)
#define PvFrame_CheckExact(op) (Py_TYPE(op) == &PvFrame_Type)

/*
 * values for State
 *
 * The lower bits up to 0x20 are used to distinguish normal/visual/op_pending
 * and cmdline/insert+replace mode.  This is used for mapping.  If none of
 * these bits are set, no mapping is done.
 * The upper bits are used to distinguish between other states.
 */
#define NORMAL		0x01	/* Normal mode, command expected */
#define VISUAL		0x02	/* Visual mode - use get_real_state() */
#define OP_PENDING	0x04	/* Normal mode, operator is pending - use
				   get_real_state() */
#define CMDLINE		0x08	/* Editing command line */
#define INSERT		0x10	/* Insert mode */
#define LANGMAP		0x20	/* Language mapping, can be combined with
				   INSERT and CMDLINE */

#define REPLACE_FLAG	0x40	/* Replace mode flag */
#define REPLACE		(REPLACE_FLAG + INSERT)
#ifdef FEAT_VREPLACE
# define VREPLACE_FLAG	0x80	/* Virtual-replace mode flag */
# define VREPLACE	(REPLACE_FLAG + VREPLACE_FLAG + INSERT)
#endif
#define LREPLACE	(REPLACE_FLAG + LANGMAP)

#define NORMAL_BUSY	(0x100 + NORMAL) /* Normal mode, busy with a command */
#define HITRETURN	(0x200 + NORMAL) /* waiting for return or command */
#define ASKMORE		0x300	/* Asking if you want --more-- */
#define SETWSIZE	0x400	/* window size has changed */
#define ABBREV		0x500	/* abbreviation instead of mapping */
#define EXTERNCMD	0x600	/* executing an external command */
#define SHOWMATCH	(0x700 + INSERT) /* show matching paren */
#define CONFIRM		0x800	/* ":confirm" prompt */
#define SELECTMODE	0x1000	/* Select mode, only for mappings */

#define MAP_ALL_MODES	(0x3f | SELECTMODE)	/* all mode bits used for
						 * mapping */

PyObject *PvWindow_Remove(PyObject *win);
PyObject *PvWindow_Update(PyObject *self, int row1, int col1, int row2, int col2);
PyObject *PvWindow_Gets(PyObject *self, int row, int col1, int col2);
pos_T PvWindow_WindowPos(PyObject *self, int row, int col);

PyObject *PvWindow_MoveTo(PyObject *self, int row, int col);
PyObject *PvWindow_MoveLeft(PyObject *self, int n);
PyObject *PvWindow_MoveRight(PyObject *self, int n);
PyObject *PvWindow_MoveUp(PyObject *self, int n);
PyObject *PvWindow_MoveDown(PyObject *self, int n);
